/*
 * License GNU LGPL
 * Copyright (C) 2012 Amrullah <amrullah@panemu.com>.
 */
package com.abc.cheque.ui;


import java.io.IOException;
import java.util.List;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;

import com.abc.cheque.common.EmailValidator;
import com.abc.cheque.common.TableData;
import com.abc.cheque.common.TiwulFXUtil;
import com.abc.cheque.control.LookupFieldController;
import com.abc.cheque.entity.Cheque;
import com.abc.cheque.entity.Contact;
import com.abc.cheque.test.DaoBase;
import com.abc.cheque.ui.form.CheckBoxControl;
import com.abc.cheque.ui.form.ChoiceBoxControl;
import com.abc.cheque.ui.form.ComboBoxControl;
import com.abc.cheque.ui.form.DateControl;
import com.abc.cheque.ui.form.Form;
import com.abc.cheque.ui.form.Form.Mode;
import com.abc.cheque.ui.form.LookupControl;
import com.abc.cheque.ui.form.NumberControl;
import com.abc.cheque.ui.form.TextControl;
import com.abc.cheque.ui.table.TableControl;

/**
 *
 * @author Amrullah <amrullah@panemu.com>
 */
public class FrmPersonMaintenance extends BorderPane {

    @FXML
    private Button btnAdd;
    @FXML
    private Button btnEdit;
//    @FXML
//    private Button btnReload;
    @FXML
    private Button btnSave;
    @FXML
    private CheckBoxControl chkAlive;
    @FXML
    private ComboBoxControl<String> cmbBirthPlace;
    @FXML
    private ChoiceBoxControl<Character> cmbGender;
    @FXML
    private LookupControl<Cheque> lkupInsurance;
    @FXML
    private DateControl txtBirthDate;
    @FXML
    private TextControl txtEmail;
    @FXML
    private TextControl txtInsuranceName;
    @FXML
    private TextControl txtName;
    @FXML
    private NumberControl<Integer> txtVersion;
    @FXML
    private NumberControl<Integer> txtVisit;
    @FXML
    private NumberControl<Double> txtWeight;
    @FXML
    private Form<Contact> contactForm;
    private DaoBase<Cheque> daoInsurance = new DaoBase<>(Cheque.class);
    private DaoBase<Contact> daoPerson = new DaoBase<>(Contact.class);

    public FrmPersonMaintenance() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("FrmPersonMaintenance.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();        
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
        initControls();
        initActionListener();
    }

    public void setPerson(Contact person) {
        contactForm.setRecord(person);
    }

    private void initControls() {
        txtName.setPropertyName(Person_.name.getName());
        txtName.setRequired(true);

        txtEmail.setPropertyName(Person_.email.getName());
        txtEmail.setRequired(true);
        txtEmail.addValidator(new EmailValidator());

        cmbBirthPlace.setPropertyName(Person_.birthPlace.getName());
        for (String location : DataGenerator.birthPlaces) {
            cmbBirthPlace.addItem(location, location);
        }
        cmbBirthPlace.setRequired(false);
        
        txtBirthDate.setPropertyName(Person_.birthDate.getName());

        cmbGender.setPropertyName(Person_.gender.getName());
        cmbGender.addItem("Male", 'm');
        cmbGender.addItem("Female", 'f');

        chkAlive.setPropertyName(Person_.alive.getName());
        chkAlive.setRequired(false);
        chkAlive.setLabel(TiwulFXUtil.getLiteral("alive.true"), TiwulFXUtil.getLiteral("alive.false"), TiwulFXUtil.getLiteral("alive.null"));

        lkupInsurance.setPropertyName(Person_.insurance.getName());
        lkupInsurance.setLookupPropertyName(Insurance_.code.getName());
        lkupInsurance.setController(insuranceLookupController);

        txtInsuranceName.setPropertyName(Person_.insurance.getName() + "." + Insurance_.name.getName());

        txtVisit.setPropertyName(Person_.visit.getName());
        txtVisit.setNumberType(Integer.class);

        txtWeight.setPropertyName(Person_.weight.getName());//default Double

        txtVersion.setPropertyName(Person_.version.getName());
        txtVersion.setNumberType(Integer.class);
        txtVersion.setEditable(false);
        contactForm.bindChildren();
    }

    private void initActionListener() {
        btnSave.setOnAction(eventHandler);
        btnEdit.setOnAction(eventHandler);
        btnAdd.setOnAction(eventHandler);
//        btnReload.setOnAction(eventHandler);
        
        btnSave.disableProperty().bind(contactForm.modeProperty().isEqualTo(Form.Mode.READ));
        btnAdd.disableProperty().bind(contactForm.modeProperty().isNotEqualTo(Form.Mode.READ));
        btnEdit.disableProperty().bind(contactForm.modeProperty().isNotEqualTo(Form.Mode.READ));
    }

    public void setMode(Mode mode) {
        contactForm.setMode(mode);
    }
    
    private EventHandler<ActionEvent> eventHandler = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent t) {
            if (t.getSource() == btnSave && personForm.validate()) {
                Contact p = personForm.getRecord();
                if (p.getId() == null) {
                    p = daoPerson.insert(p);
                } else {
                    p = daoPerson.update(p);
                    p = daoPerson.initRelationship(p, Person_.insurance.getName());
                }
                personForm.setRecord(p);
                personForm.setMode(Form.Mode.READ);
            } else if (t.getSource() == btnEdit) {
                personForm.setMode(Form.Mode.EDIT);
            } else if (t.getSource() == btnAdd) {
                personForm.setRecord(new Contact());
                personForm.setMode(Form.Mode.INSERT);
//            } else if (t.getSource() == btnReload) {
//                personForm.setValueObject(person);
//                personForm.setMode(Form.Mode.READ);
//                personForm.validate();//ensure to remove exclamation mark next to the invalid fields
            }
        }
    };
    private LookupFieldController<Cheque> insuranceLookupController = new LookupFieldController<Cheque.class) {
        @Override
        public String[] getColumns() {
            return new String[]{
                        Insurance_.id.getName(),
                        Insurance_.code.getName(),
                        Insurance_.name.getName()
                    };
        }
        
        @Override
        protected void initCallback(VBox container, TableControl<Cheque> table) {
            container.setPrefWidth(500);
            table.getTableView().getColumns().get(2).setPrefWidth(300);
        }
        

        @Override
        protected String getWindowTitle() {
            return "Cheque";
        }
        
        @Override
        protected TableData loadData(int startIndex, List filteredColumns, List sortedColumns, List sortingTypes, int maxResult) {
            return daoInsurance.fetch(startIndex, filteredColumns, sortedColumns, sortingTypes, maxResult);
        }
    };
}
